<HTML>

<HEAD>
   <TITLE>Chapter 9 -- Handling User Input with Java</TITLE>
   <META>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#CE2910">
<H1><FONT COLOR=#FF0000>Chapter 9</FONT></H1>
<H1><B><FONT SIZE=5 COLOR=#FF0000>Handling User Input with Java</FONT></B>
</H1>
<P>
<HR WIDTH="100%"></P>
<P>
<H3 ALIGN=CENTER><FONT COLOR="#000000"><FONT SIZE=+2>CONTENTS<A NAME="CONTENTS"></A>
</FONT></FONT></H3>

<UL>
<LI><A HREF="#EventDrivenProgramming" >Event-Driven Programming</A>
<LI><A HREF="#JavaInputEvent" >Java Input Event</A>
<LI><A HREF="#awtEventHandling" >awt Event Handling</A>
<LI><A HREF="#KeyboardEvents" >Keyboard Events</A>
<LI><A HREF="#MouseEvents" >Mouse Events</A>
<LI><A HREF="#SampleAppletFlyingSaucer" >Sample Applet: Flying Saucer</A>
<LI><A HREF="#Summary" >Summary </A>
<LI><A HREF="#QA" >Q&amp;A</A>
<LI><A HREF="#Workshop" >Workshop</A>
<UL>
<LI><A HREF="#Quiz" >Quiz</A>
<LI><A HREF="#Exercises" >Exercises</A>
</UL>
</UL>
<HR>
<P>
Now that you have an idea about the role that user input plays
in games, you're ready to learn the specifics of how user input
works in Java. This lesson is devoted to the handling of user
input in Java, including the supported input devices and the methods
used to trap input events. You also learn about the event-driven
structure of Java event handling and how it applies to input events.
<P>
This lesson clearly establishes the fact that Java user input
handling is both powerful and simple. A handful of methods is
really all it takes to deal with user input in a Java game. You
get to see this firsthand by building a Java applet with keyboard
and mouse input support. Let's get started.
<H2><A NAME="EventDrivenProgramming"><B><FONT SIZE=5 COLOR=#FF0000>Event-Driven
Programming</FONT></B></A></H2>
<P>
Before getting into the details of how user input is handled in
Java, it's important that you understand how event-driven programming
works. This is important because user input in Java is heavily
based on the event-driven architecture that makes up the heart
of Java. In Java, an <I>event</I> is defined quite literally as
something that happens that you might want to know about. For
example, when a Java component gains the input focus, an event
occurs because it might be important for your applet to know about
the focus change.
<P>
An <I>event</I> is something that happens that you might want
to know about and possibly react to.
<P>
In the event-driven world of Java, the flow of your program follows
events external to your applet, as opposed to following an internally
linear program flow. This is an important point because it means
that a Java applet is in a constant state of responding to events.
The most visible events are things such as mouse clicks and key
presses, which are known as <I>input events</I>. You provide methods
that respond to these events, which are called <I>event handlers</I>.
<P>
An <I>input event</I> is an event generated by user manipulation
of an input device such as the mouse or keyboard.
<P>
<I>Event handlers</I> are special methods that are used to respond
or react to events.
<P>
Because of the inherent graphical nature of Java applets, it will
eventually become obvious to you why the event-driven programming
model is not only more convenient, but downright necessary. With
the potential of having multiple applets on a single Web page,
along with on-the-fly system configuration changes and a multitude
of other things going on, a procedural programming model would
be much more difficult to manage. The event-based model provides
a more sound solution to the problems inherent in a system with
a graphical interface, such as Java.
<P>
All events in Java are processed within the awt windowing toolkit
package, and they are tightly linked to awt components. A component
is basically a generic abstraction for a Java window. You might
recall that Java applets are themselves a specific type of component,
which means that they inherit the same event-processing features
built into the <TT><FONT FACE="Courier">Component</FONT></TT>
superclass.
<P>
A <I>component</I> is a generic abstraction of a window in Java.
<H2><A NAME="JavaInputEvent"><B><FONT SIZE=5 COLOR=#FF0000>Java
Input Event</FONT></B></A></H2>
<P>
As you just learned, user input in Java is handled through an
event-driven architecture. When the user interacts with an input
device, it results in an input event being dispatched to the component
with the input focus. In most cases, this component is the applet
window. An input event is a special type of event that notifies
an applet that something has occurred on an input device. An example
of an input event is a movement of the mouse.
<P>
Input events are crucial in Java games because they provide a
means of handling user responses. Without being able to monitor
user responses, Java games wouldn't be too exciting. User response
handling is not only important for providing an interface to the
user for playing a game; it also establishes much of the feel
of a game. Simply altering the means by which you provide user
response support can dramatically alter the play of a game. This
is an important point, one that you'll deal with later in this
lesson when you develop the Flying Saucer sample applet.
<P>
Java user event responses come in two varieties, which correspond
to the input devices supported by Java. The two types of input
events supported by release 1.0 of Java are as follows:
<UL>
<LI>Keyboard events
<LI>Mouse events
</UL>
<P>
Keyboard events are events generated by a key press on the keyboard.
Any time the user presses a key, a keyboard event is generated
that can be trapped and handled by the applet with the input focus.
Actually, a key press generates two events: a key down event and
a key up event. You'll learn more about these two types soon.
<P>
Mouse events are generated by mouse clicks and movements. Every
mouse click and mouse movement generates a corresponding mouse
input event. Like key presses, mouse clicks actually come as a
series of events: a mouse click down event and a mouse click up
event. A mouse event is also specifically targeted at mouse dragging.
Mouse dragging occurs when the mouse is moved with the button
down. Applets that want to respond to mouse clicks and movement
simply have to process these events and take action accordingly.
You learn more about processing mouse events a little later in
this lesson.
<P>
<CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Note</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
You might have noticed in the discussion of mouse events the mention of the mouse <I>button</I>, as opposed to the mouse <I>buttons</I>. This is intentional because Java only supports a single mouse button. This might seem limiting to users on some 
platforms, such as Windows, but keep in mind that Java is designed to support as many platforms as possible. Considering the fact that some platforms (such as Macintosh) have mice with a single button, it makes sense for Java to support only a single 
button.
</BLOCKQUOTE>

</TD></TR>
</TABLE></CENTER>
<P>
<H2><A NAME="awtEventHandling"><B><FONT SIZE=5 COLOR=#FF0000>awt
Event Handling</FONT></B></A></H2>
<P>
Before getting into the specific event handlers for keyboard and
mouse events, let's look at how events are handled in a general
sense in Java. The Java awt provides the <TT><FONT FACE="Courier">Event</FONT></TT>
class for encapsulating all types of events that can occur within
the system. The <TT><FONT FACE="Courier">Event</FONT></TT> class
models a generic event and has constants defined within it to
represent specific events. The <TT><FONT FACE="Courier">Event</FONT></TT>
class is used primarily by the <TT><FONT FACE="Courier">handleEvent</FONT></TT>
method of <TT><FONT FACE="Courier">Component</FONT></TT>. The
<TT><FONT FACE="Courier">handleEvent</FONT></TT> method is the
default event handler for all events, and is defined as follows:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">public boolean handleEvent(Event evt)</FONT></TT>
</BLOCKQUOTE>
<P>
Notice that <TT><FONT FACE="Courier">handleEvent</FONT></TT> takes
an <TT><FONT FACE="Courier">Event</FONT></TT> object as its only
parameter. <TT><FONT FACE="Courier">handleEvent</FONT></TT> uses
this <TT><FONT FACE="Courier">Event</FONT></TT> object to determine
what type of event has occurred. It then calls a more specific
event handler method to deal with the specific event. For example,
if a key is pressed, the <TT><FONT FACE="Courier">Event</FONT></TT>
object's <TT><FONT FACE="Courier">id</FONT></TT> member variable
is set to <TT><FONT FACE="Courier">KEY_PRESS</FONT></TT>, which
is a constant defining the key press event. <TT><FONT FACE="Courier">handleEvent</FONT></TT>
checks the value of <TT><FONT FACE="Courier">id</FONT></TT> and,
upon finding it equal to <TT><FONT FACE="Courier">KEY_PRESS</FONT></TT>,
calls the <TT><FONT FACE="Courier">keyDown</FONT></TT> handler
method. Listing 9.1 shows the key press handling portion of the
<TT><FONT FACE="Courier">handleEvent</FONT></TT> method in the
1.0 release of Java.
<HR>
<BLOCKQUOTE>
<B>Listing 9.1. The key press portion of the </B><TT><B><FONT FACE="Courier">handleEvent</FONT></B></TT><B>
method.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">public boolean handleEvent(Event evt)
{<BR>
&nbsp;&nbsp;switch (evt.id) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;...<BR>
&nbsp;&nbsp;case Event.KEY_PRESS:<BR>
&nbsp;&nbsp;&nbsp;&nbsp;return keyDown(evt, evt.key);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;...<BR>
&nbsp;&nbsp;}<BR>
&nbsp;&nbsp;return false;<BR>
}</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
The handling of other system events is very similar to that of
the <TT><FONT FACE="Courier">KEY_PRESS</FONT></TT> event. You
could easily override <TT><FONT FACE="Courier">handleEvent</FONT></TT>
to provide custom routing of event handlers, but it is rarely
necessary. Although you might not ever need to intervene with
the default event handling provided by <TT><FONT FACE="Courier">handleEvent</FONT></TT>,
it is nevertheless important to understand how it works.
<H2><A NAME="KeyboardEvents"><B><FONT SIZE=5 COLOR=#FF0000>Keyboard
Events</FONT></B></A><BR>
</H2>
<P>
Java keyboard events are generated when the user presses or releases
a key. Two standard keyboard event handler methods are supported
by the <TT><FONT FACE="Courier">Component</FONT></TT> class: <TT><FONT FACE="Courier">keyDown</FONT></TT>
and <TT><FONT FACE="Courier">keyUp</FONT></TT>. These two methods
are defined as follows:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">public boolean keyDown(Event evt, int
key)<BR>
public boolean keyUp(Event evt, int key)</FONT></TT>
</BLOCKQUOTE>
<P>
The <TT><FONT FACE="Courier">keyDown</FONT></TT> method is called
in response to the user pressing a key, and the <TT><FONT FACE="Courier">keyUp</FONT></TT>
method is called in response to the user releasing a key. Both
methods are passed an <TT><FONT FACE="Courier">Event</FONT></TT>
object and an integer key value parameter. The key value parameter,
<TT><FONT FACE="Courier">key</FONT></TT>, specifies which key
was pressed or released. The <TT><FONT FACE="Courier">Event</FONT></TT>
object parameter contains extra information relating to the keyboard
event, such as whether the Shift key was held down when the key
was pressed.
<P>
The <TT><FONT FACE="Courier">Event</FONT></TT> object contains
constants representing the different keys that can be specified
in the <TT><FONT FACE="Courier">key</FONT></TT> parameter. Table
9.1 shows a list of the more useful key constants.<BR>
<BLOCKQUOTE>
<CENTER><B>Table 9.1. Useful key constants for games.</B></CENTER>
</BLOCKQUOTE>
<P>
<CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><I>Constant</I></TD><TD WIDTH=103><I>Key</I>
</TD></TR>
<TR><TD WIDTH=78><TT><FONT FACE="Courier">UP</FONT></TT></TD>
<TD WIDTH=103>Up arrow</TD></TR>
<TR><TD WIDTH=78><TT><FONT FACE="Courier">DOWN</FONT></TT></TD>
<TD WIDTH=103>Down arrow</TD></TR>
<TR><TD WIDTH=78><TT><FONT FACE="Courier">LEFT</FONT></TT></TD>
<TD WIDTH=103>Left arrow</TD></TR>
<TR><TD WIDTH=78><TT><FONT FACE="Courier">RIGHT</FONT></TT></TD>
<TD WIDTH=103>Right arrow</TD></TR>
<TR><TD WIDTH=78><TT><FONT FACE="Courier">HOME</FONT></TT></TD>
<TD WIDTH=103>Home</TD></TR>
<TR><TD WIDTH=78><TT><FONT FACE="Courier">END</FONT></TT></TD>
<TD WIDTH=103>End</TD></TR>
<TR><TD WIDTH=78><TT><FONT FACE="Courier">PGUP</FONT></TT></TD>
<TD WIDTH=103>Page Up</TD></TR>
<TR><TD WIDTH=78><TT><FONT FACE="Courier">PGDN</FONT></TT></TD>
<TD WIDTH=103>Page Down</TD></TR>
</TABLE></CENTER>
<P>
<P>
To check whether the key pressed or released is one of these keys,
you override <TT><FONT FACE="Courier">keyDown</FONT></TT> or <TT><FONT FACE="Courier">keyUp</FONT></TT>
and compare the value of <TT><FONT FACE="Courier">key</FONT></TT>
to one of the constants. Listing 9.2 contains an example of overriding
<TT><FONT FACE="Courier">keyDown</FONT></TT> to check for the
user pressing one of the arrow keys.
<HR>
<BLOCKQUOTE>
<B>Listing 9.2. Handling arrow key presses in the </B><TT><B><FONT FACE="Courier">keyDown</FONT></B></TT><B>
method.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">public boolean keyDown(Event evt, int
key) {<BR>
&nbsp;&nbsp;switch (key) {<BR>
&nbsp;&nbsp;case Event.LEFT:<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// left arrow key pressed<BR>
&nbsp;&nbsp;&nbsp;&nbsp;break;<BR>
&nbsp;&nbsp;case Event.RIGHT:<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// right arrow key pressed<BR>
&nbsp;&nbsp;&nbsp;&nbsp;break;<BR>
&nbsp;&nbsp;case Event.UP:<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// up arrow key pressed<BR>
&nbsp;&nbsp;&nbsp;&nbsp;break;<BR>
&nbsp;&nbsp;case Event.DOWN:<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// down arrow key pressed<BR>
&nbsp;&nbsp;&nbsp;&nbsp;break;<BR>
&nbsp;&nbsp;}<BR>
&nbsp;&nbsp;return true;<BR>
}</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
This <TT><FONT FACE="Courier">keyDown</FONT></TT> method shows
that handling different key presses is as easy as providing a
<TT><FONT FACE="Courier">switch</FONT></TT> statement with <TT><FONT FACE="Courier">case</FONT></TT>
clauses for each key. Although the example here used the <TT><FONT FACE="Courier">keyDown</FONT></TT>
method for handling key presses, the <TT><FONT FACE="Courier">keyUp</FONT></TT>
method works in the same fashion.
<P>
If you need more details about the key that was pressed or released,
you can use the <TT><FONT FACE="Courier">Event</FONT></TT> object
passed into the <TT><FONT FACE="Courier">keyDown</FONT></TT> and
<TT><FONT FACE="Courier">keyUp</FONT></TT> methods. The typical
usage of the <TT><FONT FACE="Courier">Event</FONT></TT> object
in regard to key processing is to check for modifier keys. Modifier
keys are keys that can be pressed in conjunction with other input
events, such as the Shift and Control keys. The following are
the three methods in <TT><FONT FACE="Courier">Event</FONT></TT>
used to check the status of modifier keys:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">public boolean shiftDown()<BR>
public boolean controlDown()<BR>
public boolean metaDown()</FONT></TT>
</BLOCKQUOTE>
<P>
All of these methods return boolean values specifying whether
or not the key in question is being held down. Checking the status
of the modifier keys is necessary sometimes in applets that make
heavy use of the mouse. For example, you might have a drawing
applet that performs a different function if the Shift key is
held down and the mouse is moved. You probably won't need the
modifier keys in Java games, but it is still important to know
how they work. Who knows, you might think of an interesting way
to incorporate them into a game.
<H2><A NAME="MouseEvents"><B><FONT SIZE=5 COLOR=#FF0000>Mouse
Events</FONT></B></A></H2>
<P>
Mouse events occur when the user moves the mouse or clicks the
mouse button. A handful of methods exist for handling mouse events,
such as the following methods:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">public boolean mouseUp(Event evt, int
x, int y)<BR>
public boolean mouseDown(Event evt, int x, int y)<BR>
public boolean mouseMove(Event evt, int x, int y)<BR>
public boolean mouseDrag(Event evt, int x, int y)<BR>
public boolean mouseEnter(Event evt, int x, int y)<BR>
public boolean mouseExit(Event evt, int x, int y)</FONT></TT>
</BLOCKQUOTE>
<P>
All of these methods are passed an <TT><FONT FACE="Courier">Event</FONT></TT>
object and two integer parameters representing the X and Y position
of the mouse pointer. The <TT><FONT FACE="Courier">mouseUp</FONT></TT>
and <TT><FONT FACE="Courier">mouseDown</FONT></TT> methods are
called when the user presses and releases the mouse button. The
<TT><FONT FACE="Courier">mouseMove</FONT></TT> method is called
when the mouse is moved. The <TT><FONT FACE="Courier">mouseDrag</FONT></TT>
method is very similar to the <TT><FONT FACE="Courier">mouseMove</FONT></TT>
method-the only difference being that <TT><FONT FACE="Courier">mouseDrag</FONT></TT>
is called when the mouse is moved with the button held down. The
<TT><FONT FACE="Courier">mouseEnter</FONT></TT> and <TT><FONT FACE="Courier">mouseExit</FONT></TT>
methods are used to track when the mouse enters and exits the
applet window.
<P>
You can use the <TT><FONT FACE="Courier">x</FONT></TT> and <TT><FONT FACE="Courier">y</FONT></TT>
parameters passed into the mouse event handler methods to perform
any processing based on the position of the mouse. The following
code snippet contains an example of overriding the <TT><FONT FACE="Courier">mouseMove</FONT></TT>
method to output the mouse position to standard output:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">public boolean mouseMove(Event evt, int
x, int y) {<BR>
&nbsp;&nbsp;System.out.println(&quot;Mouse position = (&quot;
+ x + &quot;, &quot; + y + &quot;)&quot;);<BR>
&nbsp;&nbsp;return true;<BR>
}</FONT></TT>
</BLOCKQUOTE>
<P>
Similar to the keyboard event handlers, you can use the <TT><FONT FACE="Courier">Event</FONT></TT>
object passed in the mouse event handlers to find out additional
information such as the status of modifier keys.
<H2><A NAME="SampleAppletFlyingSaucer"><B><FONT SIZE=5 COLOR=#FF0000>Sample
Applet: Flying Saucer</FONT></B></A></H2>
<P>
Now that you have a good idea of how to process user input events
in Java, let's take a look at a sample applet that uses this newfound
knowledge. The Flying Saucer applet uses the sprite classes and
event handler methods to implement a user-controllable flying
saucer. Figure 9.1 shows what Flying Saucer looks like. The complete
source code, executable, and images for the Flying Saucer applet
are included on the accompanying CD-ROM.
<P>
<A HREF="f9-1.gif" ><B>Figure 9.1 : </B><I>The Flying Saucer sample applet.</I></A>
<P>
The <TT><FONT FACE="Courier">FlyingSaucer</FONT></TT> class models
the applet itself and takes care of all the details related to
setting up the sprite classes and handling the user input events.
Similar to the other applet classes you've developed that use
sprites, <TT><FONT FACE="Courier">FlyingSaucer</FONT></TT> contains
familiar support for the sprite classes. In fact, the only significantly
new code in the <TT><FONT FACE="Courier">FlyingSaucer</FONT></TT>
class is the code for handling user input.
<P>
Before getting into the specifics of the user input handlers,
however, take a look at two of the member variables defined in
the <TT><FONT FACE="Courier">FlyingSaucer</FONT></TT> class:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">private Sprite theSaucer;<BR>
private int    lastKey;</FONT></TT>
</BLOCKQUOTE>
<P>
The <TT><FONT FACE="Courier">theSaucer</FONT></TT> member variable
is a <TT><FONT FACE="Courier">Sprite</FONT></TT> object that holds
the flying saucer sprite. It is necessary to keep up with this
sprite outside of the sprite list because you need to be able
to alter its position and velocity based on user input events.
The <TT><FONT FACE="Courier">lastKey</FONT></TT> member variable
is used to hold the value of the last key pressed. This variable
is used to provide finer control over the flying saucer, as you'll
see later in this lesson.
<P>
The <TT><FONT FACE="Courier">keyDown</FONT></TT> method handles
all the details of supporting keyboard control of the saucer.
Listing 9.3 shows the source code for the <TT><FONT FACE="Courier">keyDown</FONT></TT>
method.
<HR>
<BLOCKQUOTE>
<B>Listing 9.3. The </B><TT><B><FONT FACE="Courier">FlyingSaucer</FONT></B></TT><B>
class's </B><TT><B><FONT FACE="Courier">keyDown</FONT></B></TT><B>
method.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">public boolean keyDown(Event evt, int
key) {<BR>
&nbsp;&nbsp;// Change the saucer velocity based on the key pressed
<BR>
&nbsp;&nbsp;Point vel = theSaucer.getVelocity();<BR>
&nbsp;&nbsp;switch (key) {<BR>
&nbsp;&nbsp;case Event.LEFT:<BR>
&nbsp;&nbsp;&nbsp;&nbsp;vel.x = -4;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;if (lastKey == Event.LEFT)<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vel.y = 0;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;break;<BR>
&nbsp;&nbsp;case Event.RIGHT:<BR>
&nbsp;&nbsp;&nbsp;&nbsp;vel.x = 4;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;if (lastKey == Event.RIGHT)<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vel.y = 0;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;break;<BR>
&nbsp;&nbsp;case Event.UP:<BR>
&nbsp;&nbsp;&nbsp;&nbsp;vel.y = -4;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;if (lastKey == Event.UP)<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vel.x = 0;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;break;<BR>
&nbsp;&nbsp;case Event.DOWN:<BR>
&nbsp;&nbsp;&nbsp;&nbsp;vel.y = 4;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;if (lastKey == Event.DOWN)<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vel.x = 0;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;break;<BR>
&nbsp;&nbsp;default:<BR>
&nbsp;&nbsp;&nbsp;&nbsp;vel.x = vel.y = 0;<BR>
&nbsp;&nbsp;}<BR>
&nbsp;&nbsp;theSaucer.setVelocity(vel);<BR>
&nbsp;&nbsp;lastKey = key;<BR>
&nbsp;&nbsp;return true;<BR>
}</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
The <TT><FONT FACE="Courier">keyDown</FONT></TT> method first
gets the current velocity of the saucer and checks to see which
key was pressed. It then alters the saucer's velocity according
to the directional arrow key pressed. The <TT><FONT FACE="Courier">lastKey</FONT></TT>
member variable is then checked to see whether this is a repeat
key press. If so, the tangential velocity component is cleared.
For example, if the left arrow key is held down, the Y velocity
component is cleared. This has the result of causing the saucer
to change from moving in a diagonal direction to moving in a pure
X or Y direction if you hold a key down, which gives the keyboard
controls a better feel. Try it out for yourself.
<P>
The <TT><FONT FACE="Courier">mouseDown</FONT></TT> and <TT><FONT FACE="Courier">mouseDrag</FONT></TT>
methods are used to handle mouse input events and position the
saucer at an absolute location:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">public boolean mouseDown(Event evt, int
x, int y) {<BR>
&nbsp;&nbsp;theSaucer.setPosition(new Point(x - (saucerSize.width
/ 2),<BR>
&nbsp;&nbsp;&nbsp;&nbsp;y - (saucerSize.height / 2)));<BR>
&nbsp;&nbsp;return true;<BR>
}<BR>
<BR>
public boolean mouseDrag(Event evt, int x, int y) {<BR>
&nbsp;&nbsp;theSaucer.setPosition(new Point(x - (saucerSize.width
/&nbsp;2),<BR>
&nbsp;&nbsp;&nbsp;&nbsp;y - (saucerSize.height / 2)));<BR>
&nbsp;&nbsp;return true;<BR>
}</FONT></TT>
</BLOCKQUOTE>
<P>
Both of these methods simply reposition the saucer at a location
centered on the current mouse position, which enables you to click
and drag the saucer around with the mouse. This might not be an
ideal usage of the mouse in most game scenarios, but it shows
how the mouse can be used to control a sprite, which can be useful.
<P>
<CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Note</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
You might be thinking that the duplicate code in the <TT><FONT FACE="Courier">mouseDown</FONT></TT> and <TT><FONT FACE="Courier">mouseDrag</FONT></TT> methods goes against good programming practice. You're right! The truth is that I didn't want to confuse 
things by having these methods call a third method, which is typically the way you avoid duplicate code in a situation like this. You might also think that <TT><FONT FACE="Courier">mouseDrag</FONT></TT> could just call <TT><FONT 
FACE="Courier">mouseDown</FONT></TT> and simply pass its parameters along. Although this technique would work in this particular case, it's generally not a good idea to directly call event handler methods yourself, primarily because the <TT><FONT 
FACE="Courier">Event</FONT></TT> parameter means different things to different event handlers.
</BLOCKQUOTE>

</TD></TR>
</TABLE></CENTER>
<P>
<H2><A NAME="Summary"><B><FONT SIZE=5 COLOR=#FF0000>Summary</FONT></B></A>
</H2>
<P>
In this lesson, you learned about Java events and the event-driven
architecture necessary to support them. More specifically, you
learned about Java input events, including the input devices capable
of generating them and how they are handled by the Java awt library.
<P>
You saw examples of using the input event handler methods to capture
and respond to keyboard and mouse events. You then finished up
the lesson with a sample applet using the sprite classes that
implements a user-controllable flying saucer supporting both keyboard
and mouse input. This sample applet brought you yet another step
closer to implementing a complete game. As a matter of fact, you're
now ready to embark on your first complete Java game; the next
lesson focuses on developing your first full-blown Java game,
Traveling Gecko.
<H2><A NAME="QA"><B><FONT SIZE=5 COLOR=#FF0000>Q&amp;A</FONT></B></A>
<BR>
</H2>

<TABLE>
<TR VALIGN=TOP><TD WIDTH=50><B>Q</B></TD><TD><B>What's the big deal with event-driven programming?</B>
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=50><B>A</B></TD><TD>Event-driven programming provides a powerful methodology for handling the complexities inherent in a graphical system. By modeling every action in the system as an event with a corresponding handler, the 
complexities are broken down into individually serviceable items.
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=50><B>Q</B></TD><TD><B>What are Java input events?</B>
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=50><B>A</B></TD><TD>They are any events generated by the user manipulating an input device such as the mouse or keyboard.
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=50><B>Q</B></TD><TD><B>What is the purpose of the <TT><B><FONT FACE="Courier">handleEvent</FONT></B></TT> method?</B>
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=50><B>A</B></TD><TD>The <TT><FONT FACE="Courier">handleEvent</FONT></TT> method acts as a router method for all events. All events must pass through <TT><FONT FACE="Courier">handleEvent</FONT></TT>, which in turn calls the 
appropriate event handler method.
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=50><B>Q</B></TD><TD><B>If the user has more than one mouse button, can I detect when the user presses one of the extra buttons?</B>
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=50> <B>A</B></TD><TD>No, Java only supports single-button mice. This is to eliminate the creation of extra button features that wouldn't be available to users (such as Macintosh users) with one button on their mice.
</TD></TR>
</TABLE>
<P>
<H2><A NAME="Workshop"><B><FONT SIZE=5 COLOR=#FF0000>Workshop</FONT></B></A>
</H2>
<P>
The Workshop section provides questions and exercises to help
strengthen your grasp on the material you learned today. Try to
answer the questions and at least put some thought into the exercises
before moving on to tomorrow's lesson. You'll find the answers
to the questions in appendix A, &quot;Quiz Answers.&quot;
<H3><A NAME="Quiz"><B>Quiz</B></A></H3>
<OL>
<LI>What is an event?
<LI>How do you determine whether the user is holding down the
Shift key while moving the mouse?
<LI>How can you detect when the mouse has been moved outside the
applet window?
<LI>How is the saucer controlled in the Flying Saucer applet?
</OL>
<H3><A NAME="Exercises"><B>Exercises</B></A></H3>
<OL>
<LI>Think of some things that can take place in a Java applet
that might generate events.
<LI>Think of some popular games and how the user input is handled
for each. Do they support the mouse? If so, how?
<LI>Add a hyperspace feature to the Flying Saucer applet. A hyperspace
feature would result in the saucer moving to a random location
if a certain key, such as the spacebar, is pressed.
<LI>Change the saucer in the Flying Saucer applet to a frame-animated
sprite.
</OL>
<P>
<HR WIDTH="100%"></P>

<CENTER><P><A HREF="ch8.htm"><IMG SRC="pc.gif" BORDER=0 HEIGHT=88 WIDTH=140></A><A HREF="index.htm"><IMG SRC="hb.gif" BORDER=0 HEIGHT=88 WIDTH=140></A><A HREF="#CONTENTS"><IMG SRC="cc.gif" BORDER=0 HEIGHT=88 WIDTH=140></A><A HREF="ch10.htm"><IMG 
SRC="nc.gif" BORDER=0 HEIGHT=88 WIDTH=140></A></P></CENTER>

<P>
<HR WIDTH="100%"></P>

</BODY>
</HTML>
